use std::fs;

use anyhow::{Ok, Result};
use async_std::{
    io::{Read, ReadExt, Write, WriteExt},
    net::TcpListener,
    stream::StreamExt,
    task,
};

use crate::utils::get_resources_path;

pub async fn run(ip: String, port: u16) {
    let tcp_listener = TcpListener::bind(format!("{}:{}", ip, port))
        .await
        .expect("Failed to bind");

    while let Some(stream) = tcp_listener.incoming().next().await {
        let stream = stream.expect("Failed to establish connection");
        task::spawn(handle_connection(stream));
    }
}

pub async fn handle_connection(mut stream: impl Read + Write + Unpin) -> Result<()> {
    // 从连接中读取1024个字节
    let mut buffer = [0; 1024];
    stream.read(&mut buffer).await?;

    let get = b"GET / HTTP/1.1\r\n";

    // 处理HTTP协议头，若不符合则返回404和对应的文件
    let (status_line, filename) = if buffer.starts_with(get) {
        ("HTTP/1.1 200 OK", "index.html")
    } else {
        ("HTTP/1.1 404 NOT FOUND", "404.html")
    };

    let filepath = get_resources_path().join(filename);
    let contents = fs::read_to_string(&filepath)?;

    let response = format!("{}\r\n\r\n{}", status_line, contents);

    stream.write(response.as_bytes()).await?;
    stream.flush().await?;

    Ok(())
}
